home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #001 (19xx)(Amiga User Group Deutschland e.V.).zip / Franz PD Disk #001 (19xx)(Amiga User Group Deutschland e.V.).adf / GFXMEM / gfxmem.c < prev    next >
C/C++ Source or Header  |  1986-10-22  |  12KB  |  399 lines

  1. /*
  2.  * Article 810 of net.micro.amiga:
  3.  * ion: version B 2.10.2 9/17/84 chuqui version 1.9 3/12/85; site unisoft.UUCP
  4.  * Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site caip.RUTGERS.EDU
  5.  * Path: unisoft!lll-lcc!lll-crg!seismo!caip!louie
  6.  * From: louie@trantor.UMD.EDU
  7.  * Newsgroups: net.micro.amiga
  8.  * Subject: GfxMem.c - graphical memory usage (New Version)
  9.  * Message-ID: <592@caip.RUTGERS.EDU>
  10.  * Date: 28 Nov 85 22:19:27 GMT
  11.  * Date-Received: 29 Nov 85 02:20:45 GMT
  12.  * Sender: daemon@caip.RUTGERS.EDU
  13.  * Organization: Rutgers Univ., New Brunswick, N.J.
  14.  * Lines: 377
  15.  * 
  16.  */
  17.  
  18. /*
  19.  * From: Louis A. Mamakos <louie@trantor.UMD.EDU>
  20.  * 
  21.  * Here's a new and much improved version of my GfxMem.c program.  It has been
  22.  * heavily revised since the last version that was distributed over the 
  23.  * info-amiga@red.rutgers.edu mailing list and net.micro.amiga newsgroup.  The
  24.  * display updating is now much more crisp, and I'm now using the timer.device
  25.  * rather than the AmigaDOS Delay() subroutine.  There was a note that the
  26.  * previous version could trash a disk while running the READ program.  I 
  27.  * tested the new version while downloading a copy of GfxMem.c (to make sure
  28.  * it got to our VAX ok), and things seemed to run just fine.  Just compile
  29.  * with the Lattice C compiler and go.  You should see two compilation warnings;
  30.  * these can be ignored.
  31.  * 
  32.  * **** Soapbox time ****
  33.  * As one of the few folks that posted any amiga programs so far, let me cast
  34.  * my vote to SOURCE POSTINGS of programs rather than BINHEXed versions.  We
  35.  * can learn a lot from each other, and hopefully avoid making the same
  36.  * stupid errors or inventing the same wheels over and over again.
  37.  * **** End Soapbox ****
  38.  * 
  39.  * The program displays two bar graphics, one for "CHIP" memory, and one for
  40.  * "FAST" memory.  Each bar graph is split into two colors; part for memory in
  41.  * use and part for memory free.  As the window is resized, the graphics are
  42.  * rescaled to the sized of the window.  If you find any bugs or have any 
  43.  * neat features that you'd like to see, let me know. 
  44.  * 
  45.  * Louis A. Mamakos  WA3YMH    Internet: louie@TRANTOR.UMD.EDU
  46.  *   University of Maryland, Computer Science Center - Systems Programming
  47.  * 
  48.  * Anyway, here it is:
  49.  */
  50.  
  51. /*
  52.  *  gfxmem.c  - graphically display available memory.  Quick program
  53.  *     that's a freebie.  Give it to anyone you please, just don't sell it.
  54.  *
  55.  *       Version 0.0 - initial version, released on INFO-AMIGA.
  56.  *       Version 0.1 - added numeric indication of available and used memory
  57.  *                     in bar graphs.
  58.  *       Version 0.2 - added condition compilation for timer.device code.  If
  59.  *                     I can figure out how to make it create timer signals,
  60.  *                     then I can define USE_TIMER for much more prompt
  61.  *                     response to window sizing attempts.  Oh well.
  62.  *       Version 0.3 - removed conditional compilation for timer.device
  63.  *                     code.  We now use the timer, and all seems well.
  64.  *       Version 0.4 - calculate character data placement according to
  65.  *                     display preferences.  Check for updated preferences
  66.  *                     while running.
  67.  *  TODO:
  68.  *       Add menu selection package to display Kbytes or percent of memory
  69.  *       used and free.
  70.  *
  71.  *       Add requestor to display statistics like min and max for free and
  72.  *       avail, time running, etc..
  73.  *
  74.  *
  75.  *                 Copyright (C) 1985,
  76.  *                 Louis A. Mamakos
  77.  *                 Software & Stuff
  78.  */
  79.  
  80. #define  PROG_VER "GfxMem 0.4 "
  81.  
  82. #include <exec/types.h>
  83. #include <exec/nodes.h>
  84. #include <exec/lists.h>
  85. #include <exec/exec.h>
  86. #include <exec/execbase.h>
  87. #include <exec/ports.h>
  88. #include <exec/devices.h>
  89. #include <exec/memory.h>
  90. #include <devices/timer.h>
  91. #include <hardware/blit.h>
  92. #include <graphics/copper.h>
  93. #include <graphics/regions.h>
  94. #include <graphics/rastport.h>
  95. #include <graphics/gfxbase.h>
  96. #include <graphics/gfxmacros.h>
  97. #include <graphics/gels.h>
  98. #include <intuition/intuition.h>
  99.  
  100. extern struct ExecBase *SysBase;
  101. struct IntuitionBase *IntuitionBase;
  102. struct GfxBase *GfxBase;
  103. struct MsgPort *timerport, *CreatePort();
  104. struct timerequest timereq;
  105.  
  106. struct NewWindow NewWindow = {
  107.    10, 10, 450, 50,           /* sizes */
  108.    -1, -1,                    /* pens */
  109.    CLOSEWINDOW | ACTIVEWINDOW | SIZEVERIFY |
  110.                  NEWSIZE | NEWPREFS | REFRESHWINDOW,   /* IDCMP flags */
  111.    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH,
  112.    NULL, NULL,                /* gadget, checkmark */
  113.    PROG_VER,                  /* title */
  114.    NULL, NULL,                /* screen, bitmap */
  115.    100, 30, 640, 100,         /* min and max sizing */
  116.    WBENCHSCREEN               /* on the workbench screen */
  117. };
  118.  
  119. ULONG    AvailMem ();
  120. ULONG    ChipMax, FastMax, ChipFree, FastFree;
  121. ULONG    ChipLargest, FastLargest;
  122. int      dont_draw, char_size;
  123.  
  124. /*
  125.  *  maxsize -- determine the total maximum size for all regions
  126.  *   of the given type.  This code must be executed while
  127.  *   FORBIDDEN (it accesses shared system structures).
  128.  */
  129. ULONG
  130. maxsize (t)
  131.     unsigned long t;
  132. {
  133.     /* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */
  134.     ULONG size = 0;
  135.     struct MemHeader *mem;
  136.     struct ExecBase *eb = SysBase;
  137.  
  138.     for (mem = (struct MemHeader *) eb->MemList.lh_Head;
  139.                         mem->mh_Node.ln_Succ; mem = mem->mh_Node.ln_Succ)
  140.        if (mem -> mh_Attributes & t)
  141.           size += ((ULONG) mem->mh_Upper - (ULONG) mem->mh_Lower);
  142.     return size;
  143. }
  144.  
  145. getsizes()
  146. {
  147.    if (ChipMax == 0) {  /* only do this once */
  148.       Forbid ();
  149.       ChipMax = maxsize (MEMF_CHIP);
  150.       FastMax = maxsize (MEMF_FAST);
  151.       Permit();
  152.    }
  153.    ChipFree = AvailMem (MEMF_CHIP);
  154.    ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST);
  155.    FastFree = AvailMem (MEMF_FAST);
  156.    FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST);
  157. }
  158.  
  159. starttimer()
  160. {
  161.    timereq.tr_time.tv_secs = 1;
  162.    timereq.tr_time.tv_micro = 0;
  163.    timereq.tr_node.io_Command = TR_ADDREQUEST;
  164.    timereq.tr_node.io_Flags = 0;
  165.    timereq.tr_node.io_Error = 0;
  166.    timereq.tr_node.io_Message.mn_ReplyPort = timerport;
  167.    SendIO((char *) &timereq.tr_node);
  168. }
  169.  
  170. /*
  171.  *  This function is called during startup and when new preferences are
  172.  *  selected.  Get the font size from the Preferences structure.
  173.  */
  174. newprefs()
  175. {
  176.    char FontHeight;
  177.  
  178.    GetPrefs(&FontHeight, sizeof (FontHeight));
  179.    switch (FontHeight) {
  180.    case TOPAZ_SIXTY:
  181.       char_size = 11;
  182.       break;
  183.  
  184.    case TOPAZ_EIGHTY:
  185.       char_size = 8;
  186.       break;
  187.  
  188.    default:
  189.       char_size = 12;
  190.    }
  191. }
  192.  
  193.  
  194. /*
  195.  *  Main function.  Call intution to create a new window for us on the
  196.  *  screen.  Go from there.
  197.  */
  198. main(argc, argv)
  199.    int argc;
  200.    char **argv;
  201. {
  202.    struct Window *w;
  203.    struct IntuiMessage *msg, *GetMsg();
  204.    int waitmask;
  205.  
  206.    timerport = NULL;
  207.    IntuitionBase = (struct IntuitionBase *)
  208.                    OpenLibrary("intuition.library", 0);
  209.    if (IntuitionBase == NULL)
  210.       exit(1);
  211.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  212.    if (GfxBase == NULL) {
  213.       CloseLibrary(IntuitionBase);
  214.       exit(2);
  215.    }
  216.  
  217.    if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) {
  218.       CloseLibrary(GfxBase);
  219.       CloseLibrary(IntuitionBase);
  220.       exit(3);
  221.    }
  222.    if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
  223.       CloseWindow(w);
  224.       CloseLibrary(GfxBase);
  225.       CloseLibrary(IntuitionBase);
  226.       exit(5);
  227.    }
  228.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
  229.       DeletePort(timerport);
  230.       CloseWindow(w);
  231.       CloseLibrary(GfxBase);
  232.       CloseLibrary(IntuitionBase);
  233.       exit(4);
  234.    }
  235.  
  236.    newprefs();
  237.    redraw(w, TRUE);
  238.    starttimer();
  239.    waitmask = (1 << w->UserPort->mp_SigBit) |
  240.               (1 << timerport->mp_SigBit);
  241.    for(;;) {
  242.       Wait(waitmask);
  243.       while (msg = GetMsg(w->UserPort)) {
  244.          switch (msg->Class) {
  245.          case CLOSEWINDOW:
  246.             ReplyMsg(msg);
  247.             AbortIO(&timereq);
  248.             CloseDevice(&timereq);
  249.             DeletePort(timerport);
  250.             CloseWindow(w);
  251.             CloseLibrary(GfxBase);
  252.             CloseLibrary(IntuitionBase);
  253.             exit(0);
  254.  
  255.          case REFRESHWINDOW:
  256.             BeginRefresh(w);
  257.             dont_draw = 0;
  258.             redraw(w, TRUE);
  259.             EndRefresh(w, TRUE);
  260.  
  261.          case ACTIVEWINDOW:
  262.             /* when window is active, display version */
  263.             SetWindowTitles(w, -1, 
  264.                 "Graphical memory display by Louis A. Mamakos");
  265.             break;
  266.  
  267.          case NEWSIZE:
  268.             dont_draw = 0;
  269.             redraw(w, TRUE);
  270.             break;
  271.  
  272.          case SIZEVERIFY:
  273.             dont_draw = 1;
  274.             break;
  275.  
  276.          case NEWPREFS:
  277.             newprefs();
  278.             redraw(w, TRUE);
  279.             break;
  280.          }
  281.          ReplyMsg(msg);
  282.       } /* while */
  283.  
  284.       if (GetMsg(timerport)) {
  285.          redraw(w, FALSE);
  286.          starttimer();
  287.       }
  288.    } /* for */
  289. }
  290.  
  291.  
  292. #define TOP w->BorderTop
  293. #define BOTTOM w->Height - w->BorderBottom
  294. #define LEFT w->BorderLeft
  295. #define RIGHT w->Width - w->BorderRight
  296. #define GUTTER 3        /* pixels of veritical spacing between bars */
  297.  
  298. /*
  299.  *  Redraw all of the stuff in the window.
  300.  */
  301. redraw(w, refresh)
  302.    struct Window *w;
  303.    int refresh;
  304. {
  305.    register struct RastPort *rp = w->RPort;
  306.    register short x_min, y_min, x_max, y_max;
  307.    static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale;
  308.    static long old_chipfree, old_fastfree;
  309.    char txt[10];
  310.  
  311.    if (dont_draw)
  312.       return 0;
  313.    getsizes();
  314.    if (refresh) {
  315.       SetAPen(rp, 2);
  316.       SetBPen(rp, 2);
  317.       SetOPen(rp, 2);
  318.       RectFill(rp, LEFT, TOP, RIGHT, BOTTOM);
  319.       /*  recalculate the spacing paramters for this sized window */
  320.       AvailWidth = w->Width - w->BorderRight - w->BorderLeft;
  321.       AvailHeight = w->Height - w->BorderTop - w->BorderBottom;
  322.       HorizSpace = AvailWidth/20; /* use 5% of available space as margin */
  323.       AvailWidth -= HorizSpace * 2;
  324.       Thickness = (AvailHeight - GUTTER*3) / 2;
  325.       if (ChipMax > FastMax)
  326.          Scale = ChipMax/AvailWidth;
  327.       else
  328.          Scale = FastMax/AvailWidth;
  329.    } else
  330.       if (old_chipfree == ChipFree && old_fastfree == FastFree)
  331.          return 0;
  332.    old_chipfree = ChipFree;
  333.    old_fastfree = FastFree;
  334.    SetAPen(rp, 3);
  335.    SetOPen(rp, 1);
  336.    SetBPen(rp, 2);
  337.    x_min = HorizSpace;
  338.    y_min = TOP + GUTTER;
  339.    x_max = x_min + (ChipMax - ChipFree)/Scale;
  340.    y_max = y_min + Thickness;
  341.    RectFill(rp, x_min, y_min, x_max, y_max);
  342.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  343.       sprintf(txt, "%4dK", (ChipMax - ChipFree) >> 10);
  344.       SetAPen(rp, 1);
  345.       SetBPen(rp, 3);
  346.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  347.       Text(rp, txt, 5);
  348.    }
  349.    x_min = x_max;
  350.    x_max = x_min + ChipFree/Scale;
  351.    SetAPen(rp, 0);
  352.    RectFill(rp, x_min, y_min, x_max, y_max);
  353.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  354.       sprintf(txt, "%4dK", ChipFree>>10);
  355.       SetAPen(rp, 1);
  356.       SetBPen(rp, 0);
  357.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  358.       Text(rp, txt, 5);
  359.    }
  360.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  361.       SetAPen(rp, 1);
  362.       SetBPen(rp, 2);
  363.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 4);
  364.       Text(rp, "C", 1);
  365.    }
  366.    x_min = HorizSpace;
  367.    x_max = x_min + (FastMax - FastFree)/Scale;
  368.    y_min = y_max + GUTTER;
  369.    y_max = y_min + Thickness;
  370.    SetAPen(rp, 3);
  371.    RectFill(rp, x_min, y_min, x_max, y_max);
  372.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  373.       sprintf(txt, "%4dK", (FastMax - FastFree) >> 10);
  374.       SetAPen(rp, 1);
  375.       SetBPen(rp, 3);
  376.       Move(rp, x_max - 5*char_size - 6, y_min + Thickness/2 + 3);
  377.       Text(rp, txt, 5);
  378.    }
  379.    x_min = x_max;
  380.    x_max = x_min + FastFree/Scale;
  381.    SetAPen(rp, 0);
  382.    RectFill(rp, x_min, y_min, x_max, y_max);
  383.    if ((Thickness > char_size) && (x_max - x_min > 6 * char_size)) {
  384.       sprintf(txt, "%4dK", FastFree>>10);
  385.       SetAPen(rp, 1);
  386.       SetBPen(rp, 0);
  387.       Move(rp,x_min + 5, y_min + Thickness/2 + 3);
  388.       Text(rp, txt, 5);
  389.    }
  390.    if ((HorizSpace > char_size + 5) && Thickness > char_size + 1) {
  391.       SetAPen(rp, 1);
  392.       SetBPen(rp, 2);
  393.       Move(rp, HorizSpace - char_size - 1, y_min + Thickness/2 + 3);
  394.       Text(rp, "F", 1);
  395.    }
  396. }
  397.  
  398.  
  399.